import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import postcss from "rollup-plugin-postcss";
import autoprefixer from 'autoprefixer'
import postcssUrl from "postcss-url";
import npmImport from 'less-plugin-npm-import';
import url from "@rollup/plugin-url";
import typescript from "rollup-plugin-typescript2";
import babel from "@rollup/plugin-babel";
import { DEFAULT_EXTENSIONS } from "@babel/core";
import terser from "@rollup/plugin-terser";
import externalsPlugin from "rollup-plugin-node-externals";
import strip from "@rollup/plugin-strip";
import alias from "@rollup/plugin-alias";
import del from "rollup-plugin-delete";
import eslint from "@rollup/plugin-eslint";
import { visualizer } from "rollup-plugin-visualizer";
import copy from "rollup-plugin-copy";
import path from "path";
import getPkgToolsConfig, {
  getPackageJson,
} from "../utils/getPkgToolsConfig.js";
import { __dirname, getBusinessProjectFilePath } from "../utils/index.js";
const packageJson = getPackageJson();

const pkgToolsConfig = await getPkgToolsConfig();
console.log("pkgToolsConfig", pkgToolsConfig);
const {
  esDir,
  cjsDir,
  umdDir,
  storybook,
  robotConfig,
  outputPath,
  storybookConfig,

  input,
  outputDir,
  outputEsDir,
  outputCjsDir,
  outputUmdDir,
  output: {
    umd = false,
    name: variableName = undefined,
    globals = {},
    ...restOutput
  } = {},
  external = [],
  eslintOptions = {},
  externalsOptions = {},
  aliasOptions = {
    entries: [],
    extensions: [],
  },
  resolveOptions = {},
  commonjsOptions = {},
  urlOptions = {},
  typescriptOptions = {},
  babelOptions = {},
  postcssOptions = {
    plugins: [],
  },
  stripOptions = {
    labels: [],
  },
  terserOptions = {},
  deleteOptions = {},
  visualizerOptions = {},
  copyOptions = {
    targets: [],
  },
  copyToDistExt = [".less", ".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg"],

  // Rollup 其他配置
  ...restRollupProps
} = pkgToolsConfig || {};

// 首选解析后缀
const customResolver = resolve({
  extensions: aliasOptions.extensions || [
    ".js",
    ".ts",
    ".jsx",
    ".tsx",
    ".less",
    ".scss",
  ],
});
const projectRootDir = path.resolve(__dirname);

const isProduction = process.env.NODE_ENV === "production";

// 获取 plugins
const getPlugins = (format) => {
  const isUmd = format === "umd";
  const analyzer = process.env.package_cli_service_analyzer;
  delete process.env.package_cli_service_analyzer;
  return [
    // 自动将dependencies依赖声明为
    externalsPlugin({
      // 所有选项都是可选的
      // 如果你要是用某些 shims/polyfills，可以将此选项设置为false。默认: true.
      // builtins?: boolean
      // 导入node内置的前缀处理。 默认: 'add'.
      // builtinsPrefix?: 'add' | 'strip'
      // 到package.json的路径
      // packagePath?: string | string[]
      // 将pkg.dependencies设置为外部的。默认: true.
      // deps?: boolean
      // 使pkg.devDependencies成为外部的。默认: false.
      // devDeps?: boolean
      // 将pkg.peerDependencies设置为外部。 默认: true.
      // peerDeps?: boolean
      // 将pkg.optionalDependencies设置为外部的。 默认: true.
      // optDeps?: boolean
      // 将模块强制设置为外部依赖。 默认: [].
      // include?: string | RegExp | (string | RegExp)[]
      // 将模块强制排除外部依赖。 默认: [].
      // exclude?: string | RegExp | (string | RegExp)[]
      ...externalsOptions,
    }),
    alias({
      entries: [
        { find: "@", replacement: path.resolve(projectRootDir, "./src") },
        ...aliasOptions.entries,
      ],
      customResolver,
    }),
    eslint({
      // throwOnError: true,
      // throwOnWarning: true,
      exclude: [
        "node_modules/**",
        "**/*.less",
        "**/*.css",
        "**/*.jpg",
        "**/*.jpeg",
        "**/*.png",
        "**/*.gif",
        "**/*.webp",
        "**/*",
      ],
      ...eslintOptions,
    }),
    resolve({
      extensions: [".js", ".ts", ".jsx", ".tsx", ".json", ".less"],
      ...resolveOptions,
    }),
    commonjs({
      ...commonjsOptions,
    }),
    url({
      fileName: "[dirname][name][extname]",
      sourceDir: getBusinessProjectFilePath("src"),
      ...urlOptions,
    }),
    !isUmd &&
      typescript({
        ...typescriptOptions,
      }),
    babel({
      extensions: [
        // @rollup/plugin-babel默认只查看带有这些扩展名的代码:.js，.jsx，.es6，.es，.mjs。要解决这个问题，可以将.ts和.tsx添加到扩展名列表中。
        ...DEFAULT_EXTENSIONS,
        ".ts",
        ".tsx",
      ],
      babelHelpers: "runtime",
      exclude: "node_modules/**", // 只编译我们的源代码
      presets: [
        [
          "@babel/preset-env",
          {
            modules: false,
            useBuiltIns: "usage",
            corejs: 3,
          },
        ],
        "@babel/preset-react",
        "@babel/preset-typescript",
      ],
      plugins: ["@babel/plugin-transform-runtime"],

      ...babelOptions,
    }),
    postcss({
      // extract: true,
      // minimize: true,
      ...postcssOptions,
      plugins: [
        autoprefixer(),
        postcssUrl({
          url: "inline", // enable inline assets using base64 encoding
          maxSize: 100, // maximum file size to inline (in kilobytes)
          fallback: "copy", // copy, rebase or custom function for files > maxSize
          includeUriFragment: true, // 在 URI 末尾包含片段标识符
          ignoreFragmentWarning: true, // 内联带有片段的 SVG URL 时不发出警告
          optimizeSvgEncode: true, // 减小内联 svg 的大小（IE9+，Android 3+）
        }),

        ...postcssOptions.plugins,
      ],
      use: {
        less: {
          plugins: [new npmImport({ prefix: '~' })], // 使用带～前缀引入less文件
          javascriptEnabled: true
        },
      }
    }),
    strip({
      ...stripOptions,
      labels: ["unittest", ...stripOptions.labels],
    }),
    terser({
      ...terserOptions,
    }),
    del({
      targets: `${outputDir}/*`,
      ...deleteOptions,
    }),
    analyzer &&
      visualizer({
        filename: `./dist-visualizer/stats.html`,
        title: `${packageJson.name} visualizer`,
        open: true,
        template: "treemap",
        gzipSize: true,
        ...visualizerOptions,
      }),
    copy({
      ...copyOptions,
      targets: [
        {
          src: copyToDistExt.map((ext) => `src/**/*${ext}`),
          dest: [outputEsDir, outputCjsDir],
          rename: (name, extension, fullPath) => {
            const fullPathArr = fullPath.split("/");
            return fullPathArr.slice(1).join("/");
          },
        },
        ...copyOptions.targets,
      ],
    }),
  ];
};

const config = [
  {
    input,
    output: [
      {
        dir: outputCjsDir,
        format: "cjs",
        exports: "named",
        preserveModules: true,
        preserveModulesRoot: "src",
        ...restOutput,
      },
      {
        dir: outputEsDir,
        format: "es",
        exports: "named",
        preserveModules: true,
        preserveModulesRoot: "src",
        ...restOutput,
      },
    ],
    external: [/@babel\/runtime/, ...external],
    plugins: getPlugins(),
    ...restRollupProps,
  },
];

const umdConfig = {
  input,
  output: {
    file: `${pkgToolsConfig.umdDir}/${variableName}.min.js`,
    format: "umd",
    name: variableName,
    // { jquery: "$" } 此处 $ 是外部的引用，jquery是定义的内部模块
    globals: globals,
  },
  // 将[模块]视为外部依赖项
  external: external,
  plugins: getPlugins("umd"),
  ...restRollupProps,
};

export default () => {
  if (umd) {
    config.push(umdConfig);
  }
  return config;
};
